/**
 * created  on 22/09/2017.
 */



window.addEventListener("load", function () {
    ApiUserManageMain.init();
});

/**
 * 整个脚本的初始化入口
 *
 */
const ApiUserManageMain = {


    init: function () {
        ApiUserSearchBox.init();
        ApiUserTableBox.init();
    }
};

const ApiUserSearchBox = {

    box: null,

    form: null,

    init: function () {
        this.box = document.querySelector("div.box.search-box");
        this.form = this.box.querySelector("form.search-form");

        //事件监听器

        this.form.querySelector("button.btn.search-btn").addEventListener("click", function () {
            ApiUserSearchBox.search();
        });

        this.form.appKey.addEventListener("keydown", function (event) {
            let keyCode = 13;
            if (event.which == keyCode || event.keyCode == keyCode) {
                ApiUserSearchBox.search();
            }
        });

    },
    search: function () {
        let input, value;
        input = this.form.appKey;
        let params;
        params = new Params();

        value = input.value.trim();
        if (value) {
            params[this.form.appKey.name] = value;
        }

        // 刷新 table
        ApiUserTableBox.refresh(this.form.action, params);

    }, getForm: function () {
        return this.form;
    }


};

/**
 * 负责 Table 的显示逻辑
 */
const ApiUserTableBox = {


    _url_: null,

    _tableBox_: null,

    _params_: null,

    _overlayDiv_: null,

    _draw_: 0,

    _dataTable_: null,

    _table_: null,


    _language_: {
        processing: "飞速加载中",
        emptyTable: "没有搜索到符合的结果",
        zeroRecord: "没有匹配的结果",
        paginate: {
            first: "首页",
            last: "尾页",
            previous: "上一页",
            next: "下一页"
        },
        select: {
            rows: "%d 行已选择"
        },
        info: "显示 _START_ 至 _END_   共 _TOTAL_ 行",
        lengthMenu: "每页显示 _MENU_ 行",
        search: "过滤:"
    },

    _createButton_: {
        // className: "btn btn-primary Add",
        text: "添加",
        action: function (e, dt, node, config) {
            ApiUserTableEventHandler.buttonAdd(e, dt, node, config);
        }
    },

    _updateButton_: {
        className: "btn btn-primary Edit disabled onlyOne",
        text: "编辑",
        action: function (e, dt, node, config) {
            ApiUserTableEventHandler.buttonEdit(e, dt, node, config);
        }
    },

    _httpPermitButton_: {
        className: "btn btn-primary Edit disabled onlyOne",
        text: "HttpPermit",
        action: function (e, dt, node, config) {
            ApiUserTableEventHandler.httpPermitButton(e, dt, node, config);
        }
    },

    _deleteButton_: {
        className: "btn btn-danger Del disabled onlyOne",
        text: "删除",
        action: function (e, dt, node, config) {
            ApiUserTableEventHandler.buttonDelete(e, dt, node, config);
        }
    },

    _refreshPublicKeyButton_: {
        className: "btn btn-primary grant disabled onlyOne",
        text: "刷新PublicKey",
        action: function (e, dt, node, config) {
            ApiUserTableEventHandler.refreshPublicKey(e, dt, node, config);
        }
    },

    _refreshHttpPermitButton_: {
        className: "btn btn-primary grant disabled onlyOne",
        text: "刷新HttpPermit",
        action: function (e, dt, node, config) {
            ApiUserTableEventHandler.refreshHttpPermit(e, dt, node, config);
        }
    },

    _columns_: [
        {
            "searchable": false,
            "title": "序号",
            "className": "row-num text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = parseInt(meta.row) + 1;
                        break;
                    case 'set':
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "rowNum",
            "orderable": false,
            "type": "num"
        },
        {
            "searchable": false,
            "title": "ID",
            "className": "id text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.id;
                        break;
                    case 'set':
                        row.id = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "id",
            "orderable": false,
            "type": "num"

        },
        {
            "searchable": false,
            "title": "AppKey",
            "className": "app-key text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.appKey;
                        break;
                    case 'set':
                        row.appKey = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "appKey",
            "orderable": false,
            "type": "string"
        },
        {
            "searchable": false,
            "title": "公钥",
            "className": "public-key text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.publicKey;
                        if (cellData) {
                            cellData = cellData.substring(0, 15) + "...";
                        }
                        break;
                    case 'set':
                        row.publicKey = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "publicKey",
            "orderable": false,
            "type": "string",
            "createdCell": function (cell, cellData, rowData, rowIndex, colIndex) {
                cell.title = "点击看详情";
                cell.classList.add("text-primary");
                cell.addEventListener("click", function () {
                    ApiUserTableEventHandler.publicKeyClick(this, rowData.appKey, rowData.publicKey,);
                });
            }

        },
        {
            "searchable": false,
            "title": "创建时间",
            "className": "crate-time text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.createTime;
                        break;
                    case 'set':
                        row.createTime = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "createTime",
            "orderable": false,
            "type": "string"

        }, {
            "searchable": false,
            "title": "更新时间",
            "className": "update-time text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.updateTime;
                        break;
                    case 'set':
                        row.updateTime = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "updateTime",
            "orderable": false,
            "type": "string"

        },
        {
            "searchable": false,
            "title": "版本",
            "className": " text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.version;
                        break;
                    case 'set':
                        row.version = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "version",
            "orderable": false,
            "type": "string"

        },
        {
            "searchable": false,
            "title": "可见",
            "className": "visible text-nowrap text-center",
            "data": function (row, type, val, meta) {
                let cellData;
                switch (type) {
                    case 'display':
                        cellData = row.visible;
                        break;
                    case 'set':
                        row.visible = val;
                        break;
                    case'filter':
                    default :
                }
                return cellData;
            },
            "defaultContent": "--",
            "name": "visible",
            "orderable": false,
            "type": "string"

        }
    ],


    init: function () {
        this._tableBox_ = document.querySelector("div.box.table-box");
        this._table_ = this._tableBox_.querySelector("table.table.data-view");
        this._searchIfUserNoAction_();
    },
    _searchIfUserNoAction_: function () {
        let task = null, _this;
        _this = this;
        let callBack = function () {
            if (!_this._dataTable_) {
                _this.refresh(
                    ApiUserSearchBox.getForm().action
                    , new Params()
                );
            }

            if (task) {
                window.clearTimeout(task);
            }
        };

        task = window.setTimeout(callBack, 2000);
    },
    /**
     * 第一次搜索时由 refresh 调用.
     * 完成成以下功能:
     * 1.初始化 table
     * 2.初始化 table 事件处理器
     */
    initDataTable: function () {
        let _this;
        _this = this;
        $.fn.dataTable.ext.errMode = 'none';

        let settings = this._getSetting_();
        this._dataTable_ = $(this._table_).DataTable(settings);


        this._dataTable_.on("xhr.dt", function (e, settings, json, xhr) {
            _this._convertJson_(json)
        });
        this._dataTable_.on('select', function (e, dt, type, indexes) {
            ApiUserTableEventHandler.select(e, dt, type, indexes);
        });
        this._dataTable_.on('deselect', function (e, dt, type, indexes) {
            ApiUserTableEventHandler.deselect(e, dt, type, indexes);
        });

        ApiUserTableEventHandler.init(this._tableBox_, this._dataTable_);

    },
    /**
     * 返回 data table 的配置
     ** @private
     */
    _getSetting_: function () {
        return {
            serverSide: true,
            info: true,
            dom: 'lBrtip',
            scrollX: true,
            /* scrollY: "50vh",*/
            autoWidth: false,
            searching: false,
            columns: this._columns_,
            language: this._language_,
            rowId: "id",
            processing: true,
            // scrollCollapse: false,
            buttons: this._getVisibleButton_(),
            //keys: false,
            select: true,
            pagingType: "full_numbers",
            ordering: false,
            ajax: {
                url: this._url_,
                data: function (data, settings) {
                    ApiUserTableBox._data_(data, settings);
                },
                dataSrc: "data.data"
            }
        };
    },
    /**
     *
     * 将服务器返回的 json 进行转换以便 data table 能够显示.
     * 此方法由 DataTable 的  xhr.dt 事件处理器调用.
     * @param jsonResult 要被转换的 json 对象
     * @private
     */
    _convertJson_: function (jsonResult) {
        if (jsonResult.code === "ok") {
            jsonResult.recordsTotal = jsonResult.data.recordsTotal;
            jsonResult.recordsFiltered = jsonResult.data.recordsFiltered;
        }
    },
    /**
     *根据用户拥有的许可返回相应的按钮
     * @private
     */
    _getVisibleButton_: function () {
        let buttons;
        buttons = [];
        buttons.push(this._createButton_);
        buttons.push(this._updateButton_);
        buttons.push(this._httpPermitButton_);
        buttons.push(this._refreshPublicKeyButton_);
        buttons.push(this._refreshHttpPermitButton_);
        return buttons;
    },
    /**
     * 处理发送至服务器的 参数 .
     * 此方法由 DataTable 调用
     * @param data
     * @param settings
     * @private
     */
    _data_: function (data, settings) {
        let first, max;
        for (let key in data) {
            switch (key) {
                case "start":
                    first = data[key];
                    break;
                case "length":
                    max = data[key];
                    break;
                case "":
            }
            delete data[key];
        }
        data.page = first / max + 1;
        data.rows = max;
        $.extend(data, this._params_);
    },
    /**
     * 当 用户点击搜索按钮时调用此方法刷新 table
     * @param url
     * @param params
     */
    refresh: function (url, params) {
        // 先执行
        this._url_ = url;
        this._params_ = params;
        if (!this._dataTable_) {
            this.initDataTable();
        } else {
            this._dataTable_.ajax.url(this._url_).load();
        }
        this.showTableBox();
    },
    showTableBox: function () {
        if (this._tableBox_.classList.contains("hidden")) {
            this._tableBox_.classList.remove("hidden");
        }
    },
    hideTableBox: function () {
        if (!this._tableBox_.classList.contains("hidden")) {
            this._tableBox_.classList.add("hidden");
        }
    },
    getDataTable: function () {
        return this._dataTable_;
    }, refreshCurrentPage: function () {
        this._dataTable_.draw(false);
    }, updateRowData: function (rowIndex, rowData) {
        let row;
        row = this._dataTable_.row(parseInt(rowIndex));
        row.data(rowData);
    }


};

const ApiUserTableEventHandler = {

    _dataTable_: null,

    _tableBox_: null,

    _table_: null,

    /**
     *
     * 在 data table 初始化后调用
     * @param dataTable
     */
    init: function (tableBox, dataTable) {

        this._dataTable_ = dataTable;
        this._tableBox_ = tableBox;
        this._table_ = dataTable.table().node();

        // this._table_.addEventListener("keydown", function (event) {
        //     _this.deleteKey(event);
        // });
        ApiUserPublicKeyView.init();
        ApiUserUpdateEditor.init();
        ApiUserAddEditor.init();
        ApiUserHttpPermitEditor.init();
    },
    buttonGrant: function (e, dt, node, config) {
        RoleOfAdminEditor.dialogEditor(dt.row({selected: true}).data());
    },
    buttonAdd: function (e, dt, node, config) {
        ApiUserAddEditor.dialogEditor(dt);
    },
    resetPassword: function (e, dt, node, config) {
        AdminPasswordEditor.dialog(dt.row({selected: true}).data().id);
    },
    buttonDelete: function (e, dt, node, config) {
        let rowDatas;
        rowDatas = dt.rows({selected: true}).data();
        if (rowDatas.length != 1) {
            return;
        }
        //
        this._doDel_(rowDatas);
    },
    deleteKey: function (event) {
        if (event.which == 46 || event.keyCode == 46) {
            let rowDatas = this._dataTable_.rows({selected: true}).data();
            if (rowDatas.length != 1) {
                return;
            }
            this._doDel_(rowDatas);
        }
    },
    publicKeyClick: function (cell, appKey, publicKey) {
        ApiUserPublicKeyView.showDetail(appKey, publicKey);
    },
    _doDel_: function (rowDatas) {
        let params, callBack, _this;
        params = new Params();
        params["adminId"] = rowDatas[0].id;
        _this = this;
        callBack = function (data) {
            if (data.status === true) {
                $.notify({
                    icon: 'glyphicon glyphicon-leaf',
                    "title": "通知",
                    message: data.message
                }, {
                    type: "success",
                    mouse_over: "pause",
                    delay: 3000,
                    placement: {
                        align: "center"
                    },
                    animate: {
                        enter: "animated",
                        exit: "animated"
                    }
                });
                // 刷新当前页
                _this._dataTable_.ajax.reload(null, false);
            } else {
                BootstrapDialog.alert({
                    "title": '错误',
                    message: data.message,
                    type: BootstrapDialog.TYPE_DANGER,
                    closable: true,
                    draggable: true,
                    buttonLabel: '确认',
                });
            }
        };
        BootstrapDialog.confirm({
            "title": '警告',
            message: "确定要删除管理员 [ id=" + rowDatas[0].id + "] 吗?",
            type: BootstrapDialog.TYPE_WARNING,
            closable: true,
            draggable: true,
            btnCancelLabel: '取消',
            btnOKLabel: '确认',
            btnOKClass: 'btn-warning',
            callback: function (result) {
                if (result) {
                    $.post(RoamCloudManage.userPath + "/deleteAdmin", params, callBack, "json");
                }
            }
        });
    },
    httpPermitButton: function (e, dt, node, config) {
        let row, rowData;
        row = dt.row({selected: true});
        rowData = row.data();
        ApiUserHttpPermitEditor.showDialog(row.index(), rowData);
    },
    buttonEdit: function (e, dt, node, config) {
        if (dt.rows({selected: true}).count() === 1) {
            let row;
            row = dt.row({selected: true});
            ApiUserUpdateEditor.dialogEditor(row)
        }
    },
    refreshPublicKey: function (e, dt, type, indexes) {
        let row, rowData, callBack, params;
        row = dt.row({selected: true});
        rowData = row.data();

        callBack = function (json) {
            if (json.code === "ok") {
                JsonMsgUtils.showSuccessMsg(json);
            } else {
                JsonMsgUtils.showErrorMsg(json);
            }
        };

        params = new Params();
        params["appKey"] = rowData.appKey;

        $.post("security/staff/refreshPublicKey", params, callBack, "json");
    }, refreshHttpPermit: function (e, dt, type, indexes) {
        let row, rowData, callBack, params;
        row = dt.row({selected: true});
        rowData = row.data();

        callBack = function (json) {
            if (json.code === "ok") {
                JsonMsgUtils.showSuccessMsg(json);
            } else {
                JsonMsgUtils.showErrorMsg(json);
            }
        };

        params = new Params();
        params["appKey"] = rowData.appKey;

        $.post("security/staff/refreshHttpPermit", params, callBack, "json");
    }, select: function (e, dt, type, indexes) {
        DataTableUtils.decisionButtonVisible(dt);

    },
    deselect: function (e, dt, type, indexes) {
        DataTableUtils.decisionButtonVisible(dt);
    }

};

const ApiUserAddEditor = {

    _dialogDiv_: null,

    _dialogEditor_: null,

    _form_: null,


    /**
     * 在 {@link ApiUserTableEventHandler#init}  中调用
     */
    init: function () {
        this._dialogDiv_ = document.querySelector("div.modal.edit-dialog.add");
        this._form_ = this._dialogDiv_.querySelector("form.form-edit.add");
    },
    _initDialogEditor_: function () {
        let _this, e;
        _this = this;

        this._dialogEditor_ = $(this._dialogDiv_).modal({
            show: false,
            keyboard: true,
            backdrop: "static"
        });
        // 提交按钮
        e = this._dialogDiv_.querySelector("div.modal-footer button.btn.submit");
        e.addEventListener("click", function () {
            _this.save();
        });

    },

    /**
     *
     * @param dt dataTable 对象
     */
    dialogEditor: function (dt) {
        if (!this._dialogEditor_) {
            this._initDialogEditor_();
        }
        FormUtils.formInBoxDisabled(this._dialogDiv_, this._form_, false);
        this._initForAdd_(dt);
        this._showDialog_(true);
    },
    _initForAdd_: function (dt) {
        this._dialogDiv_.querySelector(".modal-title").innerHTML = "添加 Api 用户";
        //后 reset
        this._form_.reset();
    },

    save: function () {
        FormUtils.formInBoxDisabled(this._dialogDiv_, this._form_, true);

        let input, textarea, params, callBack, _this;

        input = this._form_.appKey;
        textarea = this._form_.publicKey;
        params = new Params();

        params.appKey = input.value.trim();
        params.publicKey = textarea.value.trim();

        _this = this;
        callBack = function (json) {
            _this._saveCallBack_(json);
        };

        $.post(this._form_.action, params, callBack, "json");

    },
    _saveCallBack_: function (json) {
        this._showDialog_(false);
        FormUtils.formInBoxDisabled(this._dialogDiv_, this._form_, false);

        if (json.code === "ok") {
            JsonMsgUtils.showSuccessMsg(this._getAddSuccessMsg_(json));
            //刷新本页
            ApiUserTableBox.getDataTable().draw(false);
        } else {

            JsonMsgUtils.showErrorMsg(this._getAddFailureMsg_(json));
        }

    },
    _showDialog_: function (show) {
        if (show) {
            this._dialogEditor_.modal("show");
        } else {
            this._dialogEditor_.modal("hide");
        }

    },
    _getAddFailureMsg_: function (json) {
        let message;
        message = json.msg;
        if (json.data) {
            message += "<br/>";
            for (let key in json.data) {
                message += key + " : " + json.data[key];
                message += "<br/>";
            }
        }
        return message;
    },
    _getAddSuccessMsg_: function (json) {
        let message;
        message = json.msg + '(已刷新本页),<strong class="text-danger">新数据 不一定显示在本页</strong>' + '<br/>';
        message += "已添加 Http 权限 : " + json.data.permit;
        return message;
    }
};


const ApiUserUpdateEditor = {

    _dialogDiv_: null,

    _dialogEditor_: null,

    _form_: null,

    _publicKeyChange_: false,


    /**
     * 在 {@link ApiUserTableEventHandler#init}  中调用
     */
    init: function () {
        this._dialogDiv_ = document.querySelector("div.modal.edit-dialog.update");
        this._form_ = this._dialogDiv_.querySelector("form.form-edit.update");
    },
    _initDialogEditor_: function () {
        let _this, e;
        _this = this;

        this._dialogEditor_ = $(this._dialogDiv_).modal({
            show: false,
            keyboard: true,
            backdrop: "static"
        });
        // 提交按钮
        e = this._dialogDiv_.querySelector("div.modal-footer button.btn.submit");
        e.addEventListener("click", function () {
            _this.save();
        });
        /* this._form_.querySelector("textarea.editor").addEventListener("change",function () {
             _this._publicKeyChange_ = true;
         });
 */
    },

    /**
     *
     * @param dt dataTable 对象
     */
    dialogEditor: function (row) {
        if (!this._dialogEditor_) {
            this._initDialogEditor_();
        }
        FormUtils.formInBoxDisabled(this._dialogDiv_, this._form_, false);
        this._initForUpdate_(row);
        this._showDialog_(true);
    },
    _initForUpdate_: function (row) {
        let rowData;
        rowData = row.data();

        this._form_.reset();

        this._dialogDiv_.querySelector(".modal-title").innerHTML = "更新 Api 用户[appKey=" + rowData.appKey + "]";
        this._form_.setAttribute("data-rowIndex", row.index());
        this._form_["id-editor"].value = rowData.id;
        this._form_.publicKey.value = rowData.publicKey;


    },

    save: function () {
        FormUtils.formInBoxDisabled(this._dialogDiv_, this._form_, true);

        let params, callBack, _this;

        params = new Params();
        this._parseParam_(params);
        _this = this;
        callBack = function (json) {
            _this._saveCallBack_(json);
        };

        $.post(this._form_.action, params, callBack, "json");

    },
    _parseParam_: function (params) {
        let editorArray = this._form_.querySelectorAll(".editor");
        for (let i = 0; i < editorArray.length; i++) {
            let value, editor;
            editor = editorArray[i];
            value = editor.value.trim();
            if (value) {
                params[editor.name] = value;
            }
        }
    }, _saveCallBack_: function (json) {
        this._showDialog_(false);
        FormUtils.formInBoxDisabled(this._dialogDiv_, this._form_, false);

        if (json.code === "ok") {

            this._showSuccess_(this._getSuccessMsg_(json));
            let rowIndex;
            rowIndex = this._form_.getAttribute("data-rowIndex");

            ApiUserTableBox.updateRowData(rowIndex, json.data.apiUser);
        } else {

            this._showFailure_(this._getFailureMsg_(json));
        }

    },
    _showDialog_: function (show) {
        if (show) {
            this._dialogEditor_.modal("show");
        } else {
            this._dialogEditor_.modal("hide");
        }

    },
    _getFailureMsg_: function (json) {
        let message;
        message = json.msg;
        if (json.data) {
            message += "<br/>";
            for (var key in json.data) {
                message += key + " : " + json.data[key];
                message += "<br/>";
            }
        }
        return message;
    },
    _getSuccessMsg_: function (json) {
        let message;
        message = json.msg + '<strong class="text-danger">更新成功</strong><br/>';
        return message;
    },
    _showSuccess_: function (message) {
        $.notify({
            icon: 'glyphicon glyphicon-leaf',
            "title": "通知",
            message: message
        }, {
            type: "success",
            mouse_over: "pause",
            delay: 3000,
            placement: {
                align: "center"
            },
            animate: {
                enter: "animated",
                exit: "animated"
            }
        });
    },
    _showFailure_: function (message) {
        BootstrapDialog.alert({
            "title": '错误',
            message: message,
            type: BootstrapDialog.TYPE_DANGER,
            closable: true,
            draggable: true,
            buttonLabel: '确认',
        });
    },
    /**
     *
     * @param isProtected Boolean
     * @private
     */
    _dialogEditorProtected_: function (isProtected) {
        let submitBtn, cancelBtn, editorArray, editor;
        submitBtn = this._dialogDiv_.querySelector("div.modal-footer > button.cancel");
        cancelBtn = this._dialogDiv_.querySelector("div.modal-footer > button.submit");
        if (isProtected) {
            cancelBtn.classList.add("disabled");
            submitBtn.classList.add("disabled");
        } else {
            cancelBtn.classList.remove("disabled");
            submitBtn.classList.remove("disabled");
        }
        editorArray = this._form_.elements;
        for (let i = 0; i < editorArray.length; i++) {
            editor = editorArray[i];
            if (isProtected) {
                if (!editor.hasAttribute("disabled")) {
                    editor.classList.add("disabled");
                }
            } else {
                editor.classList.remove("disabled");
            }
        }

    }
};

/**
 * 用于显示 公钥的细节
 */
const ApiUserPublicKeyView = {

    _dialogDiv_: null,

    _dialog_: null,

    _textarea_: null,


    /**
     *
     * data table 事件处理器初始化后调用
     * @see ApiUserTableEventHandler
     */
    init: function () {
        this._dialogDiv_ = document.querySelector("div.modal.public-key.detail");
        this._textarea_ = this._dialogDiv_.querySelector("textarea.detail.display");

    }, showDetail: function (appKey, publicKeyText) {
        if (!this._dialog_) {
            this._initDialog_();
        }
        this._dialogDiv_.querySelector(".modal-title").innerHTML = appKey + " 公钥";

        this._textarea_.value = publicKeyText;

        this._dialog_.modal("show");

    }, _initDialog_: function () {
        this._dialog_ = $(this._dialogDiv_).modal({
            show: false,
            keyboard: true,
            backdrop: "static"
        });
    }

};

const ApiUserHttpPermitEditor = {

    _boxDiv_: null,

    _selectDom_: null,

    _duallistBox_: null,

    _dialogEditor_: null,

    _form_: null,

    _selectedCache_: null,

    _isBtnBusy_: null,

    _btnBusyTask_: null,

    _idToObjCache_: {},

    /**
     * 在  {@link ApiUserTableEventHandler#init} 中调用
     */
    init: function () {

        this._boxDiv_ = document.querySelector("div.modal.http-permit.duallist-box");
        this._form_ = this._boxDiv_.querySelector("form.form-edit.grant");
        this._selectDom_ = this._form_.querySelector("select.editor.http-permit");
    }, _initDialog_: function () {
        let _this;
        this._dialogEditor_ = $(this._boxDiv_).modal({
            show: false,
            keyboard: true,
            backdrop: "static"
        });
        _this = this;
        this._boxDiv_.querySelector("button.btn.submit").addEventListener("click", function () {
            _this._save_(this);
        });
        this._initDuallistBox_();
    },
    _initDuallistBox_: function () {
        this._duallistBox_ = $(this._selectDom_).bootstrapDualListbox({
            nonSelectedListLabel: '未包含权限',
            selectedListLabel: '已包含权限',
            preserveSelectionOnMove: 'all',
            moveOnSelect: false,
            selectorMinimalHeight: 200,
            filterTextClear: '显示全部',
            filterPlaceHolder: '过滤',
            moveSelectedLabel: '包含选中权限',
            moveAllLabel: '包含全部权限',
            removeSelectedLabel: '移出选中权限',
            removeAllLabel: '移出所有权限',
            infoText: '显示全部 {0}',
            infoTextFiltered: '<span class="label label-warning">已过滤至</span> {0} 项 从 {1} 项中',
            infoTextEmpty: '无'
        });
    }, _save_: function (btn) {
        if (!this._httpPermitChanged_()) {
            return;
        }
        FormUtils.formInBoxDisabled(this._boxDiv_, this._form_, true);
        let params, callBack, _this;
        _this = this;
        callBack = function (json) {
            _this._saveCallBack_(btn, json);
        };
        params = new Params();

        FormUtils.parseParam(this._form_, params);
        $.post(this._form_.action, params, callBack, "json");

        this._buttonBusy_(btn);

    }, showDialog: function (rowIndex, rowData) {
        if (!this._dialogEditor_) {
            this._initDialog_();
        }
        // 缓存
        this._putCache_(rowIndex, rowData);
        FormUtils.formInBoxDisabled(this._boxDiv_, this._form_, false);
        let callBack, _this, params;
        _this = this;
        callBack = function (json) {
            if (json.code === "ok") {
                let title;
                title = "第 " + (rowIndex + 1) + "行[" + rowData.appKey + "] Http 接口权限授予";
                _this._setTitle_(title);
                _this._refreshDualListBox_(rowIndex, rowData, json);
                _this._dialogEditor_.modal("show");
            } else {
                JsonMsgUtils.showErrorMsg(json);
            }

        };
        params = new Params();
        params.id = rowData.id;
        $.get(this._form_.getAttribute("data-find-action"), params, callBack, "json");

    }, _refreshDualListBox_: function (rowIndex, rowData, json) {
        let option, i, p, data;
        this._form_.reset();
        this._selectDom_.innerHTML = "";
        this._form_.idEditorForGrant.value = rowData.id;
        // 更新标题
        this._setTipMsg_(json);
        data = json.data["permitsOfApiUser"];
        for (i = 0; i < data.length; i++) {
            p = data[i];

            option = document.createElement("option");
            option.value = p.id;
            option.innerHTML = p.permit;
            option.selected = p.selected;

            option.title = p.desc;

            if (option.selected) {
                option.classList.add("selected-item")
            } else {
                option.classList.add("not-selected-item")
            }

            this._selectDom_.add(option);
        }
        this._duallistBox_.bootstrapDualListbox('refresh');
        this._selectedCache_ = this._duallistBox_.val();
    }, /**
     * @param optionValues 当前  的已选择的权限列表值
     * @return true 表示 权限已改变
     * @private
     */
    _httpPermitChanged_: function () {
        let changed, compare,optionValues;
        optionValues = this._duallistBox_.val();
        // true 表示 相同
        compare = function (values, cache) {
            let same = values.length === cache.length;
            if (same) {
                for (let i = 0; i < values.length; i++) {
                    if (values[i] !== cache[i]) {
                        same = false;
                        break;
                    }
                }
            }
            return same;
        };

        if (optionValues === this._selectedCache_) {
            changed = false;
        } else if (optionValues && this._selectedCache_) {
            changed = !compare(optionValues, this._selectedCache_)
        } else {
            changed = true;
        }
        return changed;
    },
    _saveCallBack_: function (btn, json) {
        this._buttonIdle_(btn);
        FormUtils.formInBoxDisabled(this._boxDiv_, this._form_, false);

        if (json.code === "ok") {
            let cache;
            cache = this._getCache_(this._form_.idEditorForGrant.value);
            this._refreshDualListBox_(cache.rowIndex, cache.rowData, json);
        }
        this._setTipMsg_(json);

    }, _putCache_: function (rowIndex, rowData) {
        let id;
        id = String(rowData.id);
        this._idToObjCache_[id] = {"rowIndex": rowIndex, "rowData": rowData};

    }, _getCache_: function (apiUserId) {
        let id;
        id = String(apiUserId);
        return this._idToObjCache_[id];
    }, _getRowIndexCache_: function (apiUserId) {
        let obj, result;
        obj = this._getCache_(apiUserId);
        if (obj) {
            result = obj["rowIndex"];
        } else {
            result = null;
        }
        return result;
    }, _getRowDataCache_: function (apiUserId) {
        let obj, result;
        obj = this._getCache_(apiUserId);
        if (obj) {
            result = obj["rowData"];
        } else {
            result = null;
        }
        return result;
    }, _buttonBusy_: function (btn) {
        let i, _this;
        this._isBtnBusy_ = true;
        i = btn.querySelector("i.fa");
        i.classList.add("fa-spin");
        i.classList.add("fa-hourglass-1");
        _this = this;
        this._btnBusyTask_ = window.setTimeout(function () {
            _this._buttonIdle_(btn);
        }, 8000);
    }, _buttonIdle_: function (btn) {
        let i;
        i = btn.querySelector("i.fa");
        i.classList.remove("fa-spin");
        i.classList.remove("fa-hourglass-1");
        if (this._btnBusyTask_) {
            try {
                window.clearTimeout(this._btnBusyTask_);
            } catch (e) {
                console.error(e);
            }
            this._btnBusyTask_ = null;
        }
        this._isBtnBusy_ = false;
    },
    _setTitle_: function (title) {

        let e;
        e = this._boxDiv_.querySelector(".modal-title > span.title");
        e.innerHTML = title;

    },
    /**
     * 设置提示消息
     * @param json
     * @private
     */
    _setTipMsg_: function (json) {
        let e;
        e = this._boxDiv_.querySelector(".modal-title > span.message");
        JsonMsgUtils.showMsgWithHelp(e,json);
    }


};